#include <sys_config.h>
#include <types.h>
#include <osal/osal.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <hld/hld_dev.h>
#include <hld/dmx/dmx_dev.h>
#include <hld/dmx/dmx.h>
#include <hld/decv/vdec_driver.h>
#ifndef NEW_DEMO_FRAME
#include <api/libpub29/lib_hde.h>
#include <api/libpub29/lib_pub27.h>
#else
#include <api/libpub/lib_hde.h>
#endif


#include <api/libosd/osd_lib.h>

#include "osdobjs_def.h"
#include "images.id"
#include "string.id"
#include "osd_config.h"

#include "menus_root.h"
#include "win_com.h"
#include "win_com_popup.h"
#include "win_com_list.h"
#include "win_signalstatus.h"

#ifdef CEC_SUPPORT
#include "cec_link.h"
#include <api/libcec/lib_cec.h>
#endif

/*******************************************************************************
*	Objects definition
*******************************************************************************/
extern CONTAINER 	g_win_volume;
extern BITMAP 		vol_bmp;
extern PROGRESS_BAR vol_bar;


static VACTION win_volume_bar_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT win_volume_bar_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);


static VACTION win_volume_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT win_volume_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

extern void win_comlst_set_style(POBJECT_HEAD pobj,UINT32 shidx,UINT32 hlidx,UINT32 slidx,UINT32 gyidx);
void win_volume_switch_clrstyle(void);

//SD
#define WIN_SH_IDX				WSTL_VOLUME_01_8BIT //WSTL_VOLUME_01
#define VOLUME_BMP_SH_IDX		WSTL_MIXBACK_IDX_06_8BIT//WSTL_MIXBACK_BLACK_IDX
#define VOLUME_SH_IDX			WSTL_VOLUME_01_BG_8BIT //WSTL_VOLUME_01_BG  //WSTL_VOLUME_01_BG
#define VOLUME_MID_SH_IDX		WSTL_NOSHOW_IDX            ///*WSTL_VOLUME_01_BG*/
#define VOLUME_FG_SH_IDX		WSTL_VOLUME_01_FG_8BIT

#ifndef SD_UI
#define W_L  198//334 //20
#define W_T  470//460//500//500334 //360 //Martin@20150109
#define W_W  602 //560
#define W_H  60  //40

#define BMP_W		60 //40
#define BMP_H		60 //40
#define BMP_L_OFF	10
#define BMP_T_OFF	((W_H - BMP_H)/2)

#define R_L_OFF   0 //100
#define R_T_OFF   14
#define R_R_OFF   4
#define R_L (W_L + R_L_OFF+100)
#define R_T (W_T)  //+10)
#define R_W	(W_W - 110 - R_R_OFF)
#define R_H	W_H
#define RCT_W		R_W
#define RCT_H		(W_H - R_T_OFF*2)
#else
#define W_L  24//334 //20
#define W_T  360//500//500334 //360
#define W_W  560 //560
#define W_H  44  //40

#define BMP_W		32 //40
#define BMP_H		44 //40
#define BMP_L_OFF	10
#define BMP_T_OFF	((W_H - BMP_H)/2)

#define R_L_OFF   50 //100
#define R_T_OFF   10
#define R_R_OFF   10
#define R_L (W_L + R_L_OFF)
#define R_T (W_T)  //+10)
#define R_W	(W_W - R_L_OFF - R_R_OFF)
#define R_H	W_H
#define RCT_W		R_W
#define RCT_H		(W_H - R_T_OFF*2)

#endif

#define LDEF_BMP(root,varBmp,nxtObj,l,t,w,h,icon)		\
	DEF_BITMAP(varBmp,root,nxtObj,C_ATTR_ACTIVE,0, \
	    0,0,0,0,0, l,t,w,h, VOLUME_BMP_SH_IDX,VOLUME_BMP_SH_IDX,VOLUME_BMP_SH_IDX,VOLUME_BMP_SH_IDX,   \
	    NULL,NULL,  \
	    C_ALIGN_LEFT | C_ALIGN_VCENTER, 0,0,icon)


#define LDEF_PROGRESS_BAR(root,varBar,nxtObj,l,t,w,h,style,rl,rt,rw,rh)	\
	DEF_PROGRESSBAR(varBar, root, nxtObj, C_ATTR_ACTIVE, 0, \
		1, 1, 1, 1, 1, l, t, w, h, VOLUME_SH_IDX, VOLUME_SH_IDX, VOLUME_SH_IDX, VOLUME_SH_IDX,\
		win_volume_bar_keymap, win_volume_bar_callback, style, 4, 0, VOLUME_MID_SH_IDX, VOLUME_FG_SH_IDX, \
		rl,rt , rw, rh, 0, 100, 50, 1)

#define LDEF_WIN(varWnd,nxtObj,l,t,w,h,focusID)		\
    DEF_CONTAINER(varWnd,NULL,NULL,C_ATTR_ACTIVE,0, \
	    0,0,0,0,0, l,t,w,h, WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,   \
	    win_volume_keymap,win_volume_callback,  \
	    nxtObj, focusID,1)


LDEF_BMP(&g_win_volume,vol_bmp,&vol_bar, W_L + BMP_L_OFF, W_T + BMP_T_OFF, BMP_W, BMP_H,IM_VOLUME)

LDEF_PROGRESS_BAR(&g_win_volume, vol_bar, NULL,R_L , R_T, R_W, R_H, PBAR_STYLE_RECT_STYLE | PROGRESSBAR_HORI_NORMAL, \
				0,R_T_OFF,RCT_W,RCT_H)

LDEF_WIN(g_win_volume,&vol_bmp,W_L,W_T,W_W,W_H,1)

/*******************************************************************************
*	Local vriable & function declare
*******************************************************************************/

static ID	volume_timer = OSAL_INVALID_ID;
UINT32 VOLUME_TIMER_TIME;
#define VOLUME_TIMER_NAME 	"vol"

void volume_timer_func(UINT unused);

/*******************************************************************************
*	key mapping and event callback definition
*******************************************************************************/

static VACTION win_volume_bar_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;

#ifdef CEC_SUPPORT
	if(api_cec_get_system_audio_control_feature()&&api_cec_get_system_audio_mode_status())
	{
		act = PROC_LEAVE;
	}
#endif	

	switch(key)
	{
#ifdef _INVW_JUICE
	case V_KEY_F_DOWN:
#endif		
	case V_KEY_LEFT:
	case V_KEY_V_DOWN:
		act = VACT_DECREASE;
		break;
#ifdef _INVW_JUICE
	case V_KEY_F_UP:
#endif		
	case V_KEY_RIGHT:
	case V_KEY_V_UP:
		act = VACT_INCREASE;
		break;
	default:
		act = VACT_PASS;
	}
	return act;	
}

static PRESULT win_volume_bar_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	PROGRESS_BAR* bar;	
	SYSTEM_DATA* sys_data;
	UINT32 vkey;

	bar = (PROGRESS_BAR*)pObj;
	
	sys_data = sys_data_get();	

	switch(event)
	{
	case EVN_PRE_CHANGE:
		break;
	case EVN_POST_CHANGE:        
        {
    		sys_data->volume = OSD_GetProgressBarPos(bar);
    		if(sys_data->volume > 0 && GetMuteState() )
    		{
                if((GetChannelParrentLock() == FALSE))
                {
        			SetMuteOnOff(TRUE);
                    SaveMuteState();
        			//added by Sharon to resolve mute clear display bug
        			restore_mute_bg();
                }
    		}
    		api_audio_set_volume(sys_data->volume);
    		api_stop_timer(&volume_timer);		 
    		volume_timer = api_start_timer(VOLUME_TIMER_NAME,VOLUME_TIMER_TIME,volume_timer_func);
        }
		ret = PROC_LOOP;
		break;
	case EVN_UNKNOWNKEY_GOT:
		ap_hk_to_vk(0, param1, &vkey);
		if(vkey == V_KEY_NULL)
		{
			ret = PROC_LOOP;
		}
		break;
	default:
		break;
	}

	return ret;		 
}

static VACTION win_volume_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act = VACT_PASS;

	switch(key)
	{
	case V_KEY_EXIT:
		act = VACT_CLOSE;
		break;
	default:
		act = VACT_PASS;
	}
	return act;
}

static PRESULT win_volume_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	SYSTEM_DATA* sys_data;
	PROGRESS_BAR* bar;

	bar = &vol_bar;

	sys_data = sys_data_get();	

#ifdef CEC_SUPPORT
	if(api_cec_get_system_audio_control_feature()&&api_cec_get_system_audio_mode_status())
	{
		return PROC_LEAVE;
	}
#endif


	switch(event)
	{
	case EVN_PRE_OPEN:
        win_volume_switch_clrstyle();        
        api_inc_wnd_count();
		VOLUME_TIMER_TIME = sys_data->osd_set.time_out;
		if(VOLUME_TIMER_TIME == 0 || VOLUME_TIMER_TIME>10)
			VOLUME_TIMER_TIME = 5;
		VOLUME_TIMER_TIME *= 1000;		
#ifdef CC_ON
		cc_vbi_show_on(FALSE);
#endif
		OSD_SetProgressBarPos(bar, sys_data->volume);
		break;
	case EVN_POST_OPEN:
		volume_timer = api_start_timer(VOLUME_TIMER_NAME,VOLUME_TIMER_TIME,volume_timer_func);
		break;
	case EVN_UNKNOWNKEY_GOT:
		ap_send_msg(CTRL_MSG_SUBTYPE_KEY, param1,FALSE);
		ret = PROC_LEAVE;
		break;
	case EVN_MSG_GOT:
		if(param1 ==  CTRL_MSG_SUBTYPE_CMD_EXIT)
		{
			ret = PROC_LEAVE;
		}
#ifdef USB_MP_SUPPORT
		else if(param1 == CTRL_MSG_SUBTYPE_STATUS_VIDEO_OVER)
		{
			ret = PROC_LEAVE;
			ap_send_msg(CTRL_MSG_SUBTYPE_STATUS_VIDEO_OVER,0,TRUE);
		}
#endif
		break;
	case EVN_PRE_CLOSE:
		// if open volume window by popup window, not clear OSD. 
		if(menu_stack_get_top() != (POBJECT_HEAD)&g_win_volume)
		{
			/* Make OSD not flickering */
			*((UINT32*)param2) &= ~C_CLOSE_CLRBACK_FLG;	
		}
		break;
	case EVN_POST_CLOSE:
		api_stop_timer(&volume_timer);		
        sys_data_save(1);
        api_dec_wnd_count();
#ifdef CC_ON
		cc_vbi_show_on(TRUE);
#endif
		break;
	default:
		;
	}


	return ret;
}


void volume_timer_func(UINT unused)
{
    UINT32 hkey;
	api_stop_timer(&volume_timer);
    ap_vk_to_hk(0, V_KEY_EXIT, &hkey);
    ap_send_msg(CTRL_MSG_SUBTYPE_KEY, hkey, TRUE); // send key instead of sending message
	//ap_send_msg(CTRL_MSG_SUBTYPE_CMD_EXIT, 1, TRUE);
}

void win_volume_switch_clrstyle(void)
{
    PPROGRESS_BAR pprbar;
    POBJECT_HEAD  pobj;
    PBITMAP       pbmp;

    pobj    = (POBJECT_HEAD) &g_win_volume;
    win_comlst_set_style(pobj,WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX);      
    pobj    = (POBJECT_HEAD) &vol_bmp;
    pbmp = &vol_bmp;
    pbmp->wIconID = IM_VOLUME;
    win_comlst_set_style(pobj,VOLUME_BMP_SH_IDX,VOLUME_BMP_SH_IDX,VOLUME_BMP_SH_IDX,VOLUME_BMP_SH_IDX);      
    pobj    = (POBJECT_HEAD) &vol_bar;
    win_comlst_set_style(pobj,VOLUME_SH_IDX,VOLUME_SH_IDX,VOLUME_SH_IDX,VOLUME_SH_IDX);      
    pprbar  = &vol_bar;
    pprbar->wTickBg = VOLUME_MID_SH_IDX;
    pprbar->wTickFg = VOLUME_FG_SH_IDX;       
}

